Начиная с Scala 2.13
, большинству коллекций предоставляется метод partitionMap
, который разделяет элементы на основе функции, которая отображает элементы либо в Right
, либо в Left
.
В нашем случае нам даже не нужна функция, которая преобразует наш ввод в Right
или Left
для определения разбиения, поскольку у нас уже есть Right
s и Left
s. Таким образом, простое использование identity
!
Тогда достаточно просто сопоставить результирующий секционированный набор левых и прав на основе наличия левых:
eithers.partitionMap(identity) match {
case (Nil, rights) => Right(rights)
case (firstLeft :: _, _) => Left(firstLeft)
}
// * val eithers: List[Either[String, Int]] = List(Right(1), Right(2), Right(3))
// => Either[String,List[Int]] = Right(List(1, 2, 3))
// * val eithers: List[Either[String, Int]] = List(Right(1), Left("error1"), Right(3), Left("error2"))
// => Either[String,List[Int]] = Left("error1")
Подробности промежуточного шага (partitionMap
):
List(Right(1), Left("error1"), Right(3), Left("error2")).partitionMap(identity)
// => (List[String], List[Int]) = (List("error1", "error2"), List(1, 3))